package fun.bigtable.kraken.web.advice;

import fun.bigtable.kraken.annotation.ApiDeprecated;
import fun.bigtable.kraken.exception.BusinessAssert;
import fun.bigtable.kraken.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 废弃接口通知
 *
 * 注意：
 * 1. 使用RequestBodyAdvice无法处理GET请求，因为GET请求没有请求体
 * 2. 因此改用HandlerInterceptor来处理所有类型的请求，包括GET请求
 * 3. 同时实现WebMvcConfigurer接口来自动注册拦截器
 */
@ControllerAdvice(annotations = RestController.class)
@Component
public class ApiDeprecatedAdvice implements HandlerInterceptor, WebMvcConfigurer {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            if (handlerMethod.getMethod().isAnnotationPresent(ApiDeprecated.class)) {
                MethodParameter methodParameter = new MethodParameter(handlerMethod.getMethod(), -1);
                checkAndThrowException(methodParameter);
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 不需要实现
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 不需要实现
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(this)
                .addPathPatterns("/**"); // 拦截所有请求
    }

    private void checkAndThrowException(MethodParameter parameter) {
        ApiDeprecated methodAnnotation = parameter.getMethodAnnotation(ApiDeprecated.class);
        BusinessAssert.ifNull(methodAnnotation, "废弃接口通知配置错误");

        String msg = methodAnnotation.msg();
        if (StringUtils.isEmpty(msg)) {
            msg = "该功能已暂停使用，请退出重新登录，或联系运营人员";
        }
        throw BusinessException.error(msg);
    }
}
